package com.yonyou.pmclouds.basecom.filter;

import com.alibaba.dubbo.rpc.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.builder.ToStringBuilder;

/**
 * @author xiejianyu
 * 2019-09-12
 * Dubbo远程调用日志打印过滤器
 */
@Slf4j
public class DubboConsumerRPCLogFilter implements Filter {

    private long counter;

    private int maxLength = 2000;

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {

        long startTime = System.currentTimeMillis();
        long seq = 0L;

        try {
            synchronized (log) {
                seq = counter++;
            }

            String request = "";
            if (invocation.getArguments() != null) {
                request = ToStringBuilder.reflectionToString(invocation.getArguments());
            }
            if (request != null && request.length() > maxLength) {
                request = request.substring(0, maxLength);
            }
            log.info("requestSeq：{}，调用方法：{}，参数：{}", seq, invocation.getMethodName(), request);

        } catch (Exception e) {
            log.warn("Dubbo调用前日志打印出错，继续执行常规调用", e);
        }

        Result result = invoker.invoke(invocation);

        try {
            if (result != null && result.getValue() != null) {
                String response = ToStringBuilder.reflectionToString(result.getValue());
                if (response != null && response.length() > maxLength) {
                    response = response.substring(0, maxLength);
                }
                log.info("responseSeq：{}，返回结果：{}", seq, response);
            } else if (result != null && result.hasException()) {
                log.info("responseSeq：{}，远程调用返回异常", seq);
            } else {
                log.info("responseSeq：{}，远程调用无返回结果", seq);
            }
            return result;
        } catch (Exception e){
            //确保一定有返回
            return result;
        } finally {
            log.trace("========== Sequence is {}, exe time is {} ", seq, System.currentTimeMillis() - startTime);
        }
    }
}
